# 导包
from pyxnat.core.uriutil import file_path
from selenium import webdriver
from selenium.common import NoSuchElementException, TimeoutException
from selenium.webdriver.common.by import By
from time import sleep
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
from config import setting
from util_tools.logs_util.recordlog import logs
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from datetime import datetime
import pytesseract
from PIL import Image
from selenium.webdriver.support.ui import Select
from util_tools.handle_data.configParse import ConfigParse

class BasePage(object):

    def __init__(self, driver):
        self.__driver = driver
        self.__wait = WebDriverWait(self.__driver, setting.WAIT_TIME)
        self.conf = ConfigParse()

    def window_max(self):
        self.__driver.maximize_window()

    def window_full(self):
        self.__driver.fullscreen_window()

    def screenshot(self):
        self.__driver.get_screenshot_as_png()

    def open_url(self, url):
        if url.startswith('http') or url.startswith('https')
            self.__driver.get(url)
            logs.info(f'打开页面：{url}')
        else:
            new_url = self.conf.get_host('host') + url
            self.__driver.get(new_url)
            logs.info(f'打开页面：{new_url}')

    def get_tag_text(self, locator: tuple):
        try:
            element = self.location_element(*locator)
            element_text = element.text
            logs.info(f'获取标签文本内容：{element_text}')
            return element_text
        except Exception as e:
            logs.error(f'获取标签文本内容出现异常，原因为：{str(e)}')

    @property
    def current_url(self):
        return self.__driver.current_url

    @property
    def title(self):
        return self.__driver.title

    def refresh(self):
        self.__driver.refresh()

    def scroll_to_button(self):
        self.__driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

    @property
    def switch_to(self):
        return self.__driver.switch_to

    def iframe(self, frame):
        try:
            self.switch_to.frame(frame)
            logs.info(f'切换到{frame}--iframe内部框架中')
        except:
            logs.error('切换到iframe框架失败！')

    def switch_to_new_tab(self):
        try:
            original_window = self.__driver.window_handles[0]
            all_window = self.__driver.window_handles
            new_window = None
            for window in all_window:
                if window != original_window:
                    new_window = window
                    break
            if new_window:
                self.switch_to.window(new_window)
                logs.info('成功切换到新标签页')
        except TimeoutException:
            logs.error('等待新标签页打开超时。')
        except NoSuchElementException:
            logs.error('未找到新标签页句柄。')
        except Exception as e:
            logs.error(f'切换窗口时发生异常：{str(e)}')

    def switch_to_tab_by_index(self, index):
        try:
            all_window = self.__driver.window_handles
            if 0 <= index < len(all_window):
                target_window = all_window[index]
                self.switch_to.window(target_window)
                logs.info(f'成功切换到第{index + 1}个标签页')
            else:
                logs.error('指定的窗口索引超出范围')
        except Exception as e:
            logs.error(f'切换窗口时发生异常：{str(e)}')

    def exit_iframe(self):
        self.switch_to.default_content()

    @property
    def alert(self):
        return self.__wait.until(ec.alert_is_present())

    def alert_confirm(self):
        self.alert.accept()

    def alert_cancel(self):
        self.alert.dismiss()

    def location_element(self, by, value):
        try:
            element = self.__wait.until(ec.presence_of_element_located((by, value)))
            logs.info(f"找到元素：{by}={value}")
            return element
        except Exception as e:
            logs.error(f"未找到元素：{by}={value}")
            raise e

    def location_elements(self, by, value):
        try:
            self.__wait.until(ec.presence_of_all_elements_located((by, value)))
            elements = self.__driver.find_elements(by, value)
            logs.info(f"找到元素列表：{by}={value}")
            return elements
        except Exception as e:
            logs.error(f"未找到元素列表：{by}={value}")
            raise e

    def click(self, locator: tuple, force=False):
        try:
            element = self.location_element(*locator)
            if not force:
                self.__driver.execute_script("arguments[0].click()", element)
            else:
                self.__driver.execute_script("arguments[0].click({force:true})", element)
            logs.info(f"元素被点击：{locator}")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def send_keys(self, locator: tuple, data):
        try:
            element = self.location_element(*locator)
            element.send_keys(data)
            logs.info(f"元素被输入内容：{locator}，输入的内容为：{data}")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def send_keys_actions(self, locator: tuple, data):
        try:
            element = self.location_element(*locator)
            ActionChains(self.__driver).move_to_element(element).click().send_keys(data).perform()
            logs.info(f"元素被输入内容：{locator}，输入的内容为：{data}")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def selects(self, locator: tuple, index):
        try:
            select = Select(self.location_element(*locator))
            select.select_by_index(index)
            logs.info(f'选择第{index}个数据')
        except NoSuchElementException as e:
            logs.error(f'元素无法定位：{e}')
            raise e

    def enter(self):
        try:
            ActionChains(self.__driver).send_keys(Keys.ENTER).perform()
            logs.info("按下回车键")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def right_click(self, locator: tuple):
        try:
            element = self.location_element(*locator)
            ActionChains(driver).context_click(element).perform()
            logs.info("执行鼠标右键点击操作")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def double_click(self, locator: tuple):
        try:
            element = self.location_element(*locator)
            ActionChains(driver).double_click(element).perform()
            logs.info("执行鼠标双击操作")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def screenshots(self, image_name):
        import os
        current_time = datetime.now().strftime("%Y%m%d%H%M%S")
        file_name = f"{image_name}-{current_time}.png"
        file_path = os.path.join(setting.FILE_PATH.get('screenshot'), file_name)
        self.__driver.get_screenshot_as_file(file_path)

    def screenshots_png(self):
        return self.__driver.get_screenshot_as_png()

    def clear(self, locator: tuple):
        try:
            element = self.location_element(*locator)
            element.clear()
            logs.info("清空文本")
        except NoSuchElementException as e:
            logs.error(f"元素无法定位：{e}")
            raise e

    def ocr_captcha(self, locator: tuple):
        captcha_element = self.location_element(*locator)
        captcha_path = setting.FILE_PATH['screenshot'] + '/captcha.png'
        captcha_element.screenshot(captcha_path)
        captcha_image = Image.open(captcha_path)
        try:
            captcha_text = pytesseract.image_to_string(captcha_image)
            logs.info(f"识别到的验证码为：{captcha_text}")
            return captcha_text
        except pytesseract.pytesseract.TesseractNotFoundError:
            logs.error("找不到tesseract，这是因为pytesseract模块依赖于TesseractOCR引擎来进行图像识别！")

    def is_element_present(self, locator: tuple):
        try:
            self.__wait.until(ec.presence_of_element_located(*locator))
            return True
        except:
            return False

    def assert_is_element_present(self, locator: tuple):
        try:
            element = self.__driver.find_element(*locator)
            assert element.is_displayed(), '元素不存在'
        except NoSuchElementException as e:
            logs.error(f'元素未找到：{e}')
            raise AssertionError('元素不存在')

    def assert_element_not_visible(self, locator: tuple):
        try:
            self.__wait.until(ec.invisibility_of_element_located(locator))
        except TimeoutException:
            logs.error('元素可见')

    def assert_title(self, expect_title):
        assert expect_title in self.title


# 测试调试
if __name__ == '__main__':
    driver = webdriver.Edge()